#include "common.h"

int main(void)
{
	int DSi_mode = 0;
	void (*func_ptr)(void);
	int i;
	while(BOOTFLAG!=1);
	if(((*((vu32*)0x04004000)) & 3)==1)DSi_mode = 1;

	for(i=0; i<16; i++)//Reset sound.
	{
		SCHANNEL_CR(i) = 0;
		SCHANNEL_SOURCE(i) = 0;
		SCHANNEL_TIMER(i) = 0;
		SCHANNEL_LENGTH(i) = 0;
	}
	REG_SOUNDCNT = 0;

	for(i=0; i<4; i++)
	{
		DMA_SRC(i) = 0;//Reset DMA.
		DMA_DEST(i) = 0;
		DMA_CR(i) = 0;
		TIMER_DATA(i) = 0;//Reset timers.
		TIMER_CR(i) = 0;
		if(DSi_mode)*((u32*)(0x04004104 + (i*0x1c))) = 0;//Reset NDMA.
	}

	memset_addrs_arm7((void*)(0x03800000 - 0x8000), (void*)(0x03800000 + 0x10000));

	REG_IE = 0;
	REG_IF = ~0;
	*((vu32*)(0x04000000-4)) = 0;//Clear IRQ stuff.
	*((vu32*)(0x04000000-8)) = ~0;
	REG_POWERCNT = 1;
	IPC_SendSync(0x5);

	memcpy_arm7((void*)NDSHEADER->arm7destination, (void*)(0x02300000 + NDSHEADER->arm7romOffset), NDSHEADER->arm7binarySize);

	BOOTFLAG = 2;
	while(REG_VCOUNT!=192);//Sync with Arm9 before jumping to the bin.
	while(REG_VCOUNT==192);
	BOOTFLAG = 3;
	
	func_ptr = (void*)NDSHEADER->arm7executeAddress;
	func_ptr();
	while(1);//Should never happen.
	return 0;
}

void memset_arm7(void* buffer, int val, size_t len)
{
	vu32 *buf = (vu32*)buffer;
	while(len>0)
	{
		*buf = val;
		buf++;
		len-=4;
	}
}

void memcpy_arm7(void* a, void* b, size_t len)
{
	vu32 *bufa = (vu32*)a;
	vu32 *bufb = (vu32*)b;
	while(len>0)
	{
		*bufa = *bufb;
		bufa++;
		bufb++;
		len-=4;
	}
}

void memset_addrs_arm7(void* start, void* end)
{
	memset_arm7(start, 0, ((int)end - (int)start));
}

void arm7stub_poolend()
{
	
}

